import { AxiosRequestConfig, AxiosResponse } from 'axios';
import { Http, http, HttpConfig, HttpMethod, InstanceCallback } from './http';

const SymbolId = Symbol('id');
const SymbolHttp = Symbol('http');

export default class Api {
  private [SymbolId]: symbol;

  private [SymbolHttp]: Http;

  protected method: HttpMethod;

  constructor() {
    this[SymbolHttp] = http;
    this.method = http.method;
  }

  /**
   * @author 戴俊明 <idaijunming@163.com>
   * @description 初始化通用http请求配置，如果已被初始化，覆盖原有配置。该方法返回的实例可做链式调用。
   * @date 2020/1/30 20:50
   **/
  protected init(config?: AxiosRequestConfig, callback?: InstanceCallback): Api {
    this[SymbolId] = this.http.create(
      {
        id: Symbol.for('Api'),
        ...config,
      },
      callback
    );
    return this;
  }

  /**
   * @author 戴俊明 <idaijunming@163.com>
   * @description 根据key初始化http请求配置，如果已被初始化，覆盖原有配置。该方法返回的实例可做链式调用。
   * @date 2020/1/30 20:53
   **/
  protected initSingle(key: string, config?: AxiosRequestConfig, callback?: InstanceCallback): Api {
    this[SymbolId] = this.http.create(
      {
        id: Symbol.for(key),
        ...config,
      },
      callback
    );
    return this;
  }
  protected initInstance = (key: string, config?: AxiosRequestConfig, callback?: InstanceCallback): Api => {
    return this.initSingle(key, config, callback) as Api;
  };

  public destroy = (): boolean => this.http.destroy(this.id);

  public request = <T, R = AxiosResponse<T>>(config: AxiosRequestConfig): Promise<R> => {
    const tmp: HttpConfig = {
      id: this.id,
      ...config,
    };
    return this.http.request(tmp);
  };

  public all = (configs: AxiosRequestConfig[]): unknown =>
    Promise.allSettled(configs.map(config => this.request(config)));

  get id(): symbol {
    return this[SymbolId];
  }

  get http(): Http {
    return this[SymbolHttp];
  }
}
